Implementing New
ClassesJavaScript supports a basic object oriented paradigm, allowing
you to implement new kinds of objects by deriving them from existing
objects.
In this tutorial we show you how to implement new JavaScript classes
in Realsoft 3D. We also explore the internal structure of Realsoft
3D and demonstrate how to transform geometric objects, create
new geometric objects, export objects to a file and create new
material objects.
Note: this tutorial is not a JavaScript tutorial. Basic knowledge
of JavaScript's object oriented programming model is assumed.
Class Header
Files
In the previous tutorials we used the include() function to load
various header files.
For example, we loaded button's header file:
include("oops/r3button.js");
Each of these header files define properties for one Realsoft 3D
class. For example, 'scripts/js/oops/r3button.js' defines the JavaScript
class corresponding to the Realsoft 3D Button class.
The substructure of 'scripts\js' folder corresponds to the library
structure of Realsoft 3D. For example, the 'oops' sub folder stands for
Realsoft's Object Oriented Programming System and it defines classes
for the r3oops library. If you buy a plug-in that supports JavaScript
you get a new folder that contains the header files corresponding to the
classes in the plug-in library.
You can also add new sub folders into 'scripts/js' folder for
your own JavaScript classes. In fact, the scripts folder should
already have 'myclasses' sub folder, which contains a number of sample
classes.
myWindow
ClassAny of the sample scripts we have gone through so far can be
turned to JavaScript classes easily.
Let's recall the first sample we went through in the previous
Intro tutorial:
include("oops/r3window.js");
window = new r3Window(R3WGA_Parent, r3MainWindow,
R3WGA_Left, 300,
R3WGA_Top, 200,
R3WGA_Width, 300,
R3WGA_Height, 200,
R3WA_ReportCloseWindow, TRUE,
R3WA_ReportNewSize, TRUE,
R3WA_Title, "Dummy Window");
window.REALIZE();
Creating window objects is straightforward, but specifying all
the above attributes creates a lot of typing overhead.
Let's assume we want to create a new JavaScript window, which
creates the above kind of a window with minimal typing overhead.
This can be done by deriving a new class which takes care of setting
the appropriate attributes for us.
include("oops/r3window.js");
// constructor function
function myWindow(name, width, height)
{
if(!arguments.length)
return;
this.base = r3Window;
// our super class
this.base(R3WGA_Parent, r3MainWindow,
R3WGA_Left, 300,
R3WGA_Top, 200,
R3WGA_Width, width,
R3WGA_Height, height,
R3WA_ReportCloseWindow, TRUE,
R3WA_ReportNewSize, TRUE,
R3WA_Title, name);
}
// derive 'myWindow' from the 'r3Window' base class
myWindow.prototype=new r3Window;
This is how to derive new classes in JavaScript. If you save
the above code as 'js/myclasses/mywindow.js', you will be able to
create windows as follows:
include("myclasses/mywindow.js");
win = new myWindow("My cool window", 300, 200);
win.REALIZE();
Note: You should not put the R3WGM_REALIZE call into a
constructor. This method should be called only once from the highest
level (whoever creates your object is responsible also for realizing
them). If you put the realize method into the constructor function
of your class, it gets called multiple times causing flickering.
Another method which you should not put into constructor functions
is 'R3WGM_FIT'.
Implementing 'myToolBar'
ClassNow that we know how to derive new JavaScript classes for
existing classes, let's go through a more practical example. Let's
create a fully functional tool bar class, which allows us to create
custom tool bars as easily as possible.
Recall the packer example we went through in the beginning of the
intro tutorial. We created a window with a packer geometric manager
and then inserted a bunch of buttons into the packer. Typically
toolbars contain one or more horizontally or vertically packed tool
buttons. So we can take the packer example as a starting point for
developing our tool bar class.
Again, we need to wrap the creation code into a constructor
function to get a proper JavaScript class defined. Because the tool
bar should be user configurable, we just create a window with an empty
packer in the constructor. Then we implement another method which
allows us to insert tool buttons into the toolbar.
So, let's see how all this can be implemented.
Here is the code:
// our tool bar consists of a window, a packer and one or more buttons
include("oops/r3button.js");
include("oops/r3window.js");
include("oops/r3packer.js");
// let the user to control the orientation of the tool bar
var MYTB_HORIZONTAL = 0
var MYTB_VERTICAL = 1
// add button with user specified label and callback function
function mytbAddTool(buttonLabel, fnCallBack)
{
button = new r3Button(R3RA_Hook, fnCallBack,
R3WGA_Parent, this,
R3GA_Text, text);
if(button) {
// insert button into the packer
this.packer.ADD(R3PAPF_FILLX, 0, button);
// tell the button where to find the project
button.layer = this.layer;
}
return button;
}
// constructor: create a window with empty packer
function myToolBar(titlebar, orientation, layer)
{
if(!arguments.length)
return;
this.base = r3Window;
this.layer = layer;
this.base(R3WGA_Left, 200,
R3WGA_Top, 150,
R3WA_ReportNewSize, TRUE,
R3WA_ReportCloseWindow, TRUE,
R3WA_Title, titlebar);
// create a packer with given orientation
this.packer = new r3Packer(0);
this.packer.SetOrientation(orientation);
// define method for inserting tool buttons
this.AddTool = mytbAddTool;
// and give the packer to the window, as usual
this.SetGmanager(this.packer);
}
myToolBar.prototype=new r3Window;
Testing 'myToolBar'
Class
The above JavaScript program can be found from
'scripts/js/myclasses/toolbars/mytoolbar.js'.
Let's add a tool button which creates an analytic sphere object.
For this we need to create a call back function. This function is
called when the user clicks the tool button. In the function we
simply create a sphere and insert it into the geometry layer.
function mySphereCallback(button, event, value)
{
// create a sphere
sphere = new r3Sphere(0);
// set some sphere specific attributes
sphere.SetRadius(0.1);
sphere.SetCenter(new r3Vect(0.1, 0.0, 0.0));
sphere.SetName("my sphere");
// insert the sphere into the project
button.layer.LOCKMUTEX(0, 0, sphere);
button.layer.INSERT(0, 0, sphere);
button.layer.RELEASE();
}
Now we have defined one callback which can create a sphere into
the current layer. We have also defined a new tool bar class.
To actually create a tool bar, enter:
tbar = new myToolBar(MYTB_HORIZONTAL, primLayer);
tbar.AddTool("Sphere", mySphereCallback);
When you click the 'Sphere' button, the 'mySphereCallback' is
called and new sphere will appear into the current project.
The 'scripts/js/myclasses/toolbars' folder contains several
JavaScript examples derived from the 'myToolBar' class.
|